﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Refract.Views;
using System.Windows;
using Rhino.Mocks;
using Microsoft.Practices.Composite.Presentation.Regions;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Composite.Regions;
using Refract.Navigation;
using System.Collections.Specialized;

namespace Refract.Tests
{
    [TestClass]
    public class NavigatorFixture
    {
        private IHtmlContext _Html;
        private IView _view;
        private const string RegionName = "testRegion";
        public const string ViewName = "View";
        private IUnityContainer _container;
        private IRegionManager _RegionManager;
        private MockRepository _mock = null;        
        Navigator _navigator = null;

        [TestMethod]
        public void Navigator_is_constructed()
        {
            Assert.IsNotNull(_navigator);
            Assert.IsNotNull(_navigator.PageItems);
        }

        [TestMethod]
        public void Navigator_page_is_registered_generically()
        {
            Expect.Call(_Html.CurrentBookmark).Return(string.Empty);
            _navigator.RegisterPage<TestViewModel>(ViewName);
            Assert.IsNotNull(_navigator.PageItems[ViewName]);
            Assert.AreEqual(typeof(TestViewModel), _navigator.PageItems[ViewName].ViewModelType);
        }

        [TestMethod]
        public void Navigator_page_is_registered()
        {
            _navigator.RegisterPage(ViewName, typeof(TestViewModel));
            Assert.IsNotNull(_navigator.PageItems[ViewName]);
            Assert.AreEqual(typeof(TestViewModel), _navigator.PageItems[ViewName].ViewModelType);
        }

        [TestMethod]
        public void Navigator_goes_to_requested_page()
        {
            Expect.Call(_Html.CurrentBookmark).Return(string.Empty);
            Expect.Call(delegate { _Html.NavigateToBookmark(ViewName); });
            _mock.ReplayAll();

            _navigator.RegisterPage<TestViewModelGeneric>(ViewName);
            _navigator.Goto(ViewName);

            _mock.VerifyAll();
            Assert.IsTrue(_RegionManager.Regions[RegionName].Views.Contains(_view));
            Assert.AreEqual(Visibility.Visible, ((View)_view).Visibility);
        }
        [TestMethod]
        public void Navigator_goes_to_page_in_hash()
        {
            
            Expect.Call(_Html.CurrentBookmark).Return(ViewName);
            Expect.Call(delegate { _Html.NavigateToBookmark(ViewName); });
            
            _mock.ReplayAll();

            _navigator.RegisterPage<TestViewModelGeneric>(ViewName);

            _mock.VerifyAll();
        }

        [TestMethod]
        [ExpectedException(typeof(KeyNotFoundException))]
        public void Navigator_handles_exception_when_navigating_to_unregistered_page()
        {            
            _navigator.Goto(ViewName);
        }

        [TestMethod]
        public void Navigator_clears_region()
        {
            Expect.Call(_Html.CurrentBookmark).Return(string.Empty);
            Expect.Call(delegate { _Html.NavigateToBookmark(ViewName); });
            _mock.ReplayAll();
            _navigator.RegisterPage<TestViewModelGeneric>(ViewName);
            _navigator.Goto(ViewName);
            _navigator.Clear();
            Assert.IsFalse(_RegionManager.Regions[RegionName].Views.Contains(_view));
            Assert.AreEqual(Visibility.Collapsed, ((View)_view).Visibility);
        }

        [TestInitialize]
        public void SetupTest()
        {
            _mock = new MockRepository();
            _container = new UnityContainer();

            _RegionManager = new RegionManager();
            _RegionManager.Regions.Add(new Region() { Name = RegionName });
            _container.RegisterInstance<IRegionManager>(_RegionManager);

            _Html = _mock.StrictMock<IHtmlContext>();                        
            _container.RegisterInstance<IHtmlContext>(_Html);

            _navigator = _container.BuildUp(new Navigator(RegionName));
            _container.RegisterInstance<INavigator>(_navigator);
            
            _view = _container.BuildUp(new View());
            _container.RegisterInstance<IView>(_view);

        }
    }
}
